﻿
namespace n_PyPanel
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using n_SG;
using n_OS;
using n_PyVM;
using n_PyVar;

//*****************************************************
//图形编辑器容器类
public class PyPanel : Panel
{
	bool LeftisPress;
	bool RightisPress;
	int Last_mX, Last_mY;
	
	//标准参考距离
	public const float StdDis = 1000;
	
	//摄像机焦距
	public float CamFocusDis;
	
	//摄像机Z轴
	public float CamZ;
	
	//摄像机位置
	public float CamMidX;
	public float CamMidY;
	
	//摄像机角度
	public float CamAngle;
	
	Font Font50;
	Font Font13;
	public string DebugMes;
	
	
	//构造函数
	public PyPanel() : base()
	{
		//CellBitmap = new Bitmap( AppDomain.CurrentDomain.BaseDirectory + "Resource\\CloseIconOn.ico" );
		
		this.BorderStyle = BorderStyle.None;
		this.BackColor = Color.Black;
		
		SetStyle(ControlStyles.UserPaint |
		         ControlStyles.AllPaintingInWmPaint |
		         ControlStyles.OptimizedDoubleBuffer |
		         ControlStyles.ResizeRedraw |
		         ControlStyles.SupportsTransparentBackColor,true);
		
		this.Dock = DockStyle.Fill;
		this.ImeMode = ImeMode.NoControl;
		
		//this.Width = Width;
		//this.Height = Height;
		
		//Cursor Cursor1 = new Cursor( AppDomain.CurrentDomain.BaseDirectory + "Resource\\myPointEdit.cur" );
		//Cursor2 = new Cursor( OS.SystemRoot + "Resource" + OS.PATH_S + "myPoint2.cur" );
		
		//this.Cursor = Cursor1;
		
		this.MouseMove += new MouseEventHandler( UserMouseMove );
		this.MouseUp += new MouseEventHandler( UserMouseUp );
		this.MouseDown += new MouseEventHandler( UserMouseDown );
		this.MouseWheel += new MouseEventHandler( UserMouseWheel );
		
		LeftisPress = false;
		RightisPress = false;
		
		Font50 = new Font( "微软雅黑", 50 );
		Font13 = new Font( "微软雅黑", 13 );
		
		InitCam();
		
		PyVar.Init();
	}
	
	//==========================================
	//摄像机系统
	
	//初始化系统放缩
	void InitCam()
	{
		CamMidX = 0;
		CamMidY = 0;
		CamAngle = 0;
		
		CamFocusDis = 1;
		CamZ = -StdDis;
	}
	
	//==========================================
	
	//仿真复位
	public void ResetSim()
	{
		PyVar.ResetSim();
	}
	
	//==========================================
	
	//屏幕到世界坐标变换
	void GetWorldTrans( float mX, float mY, float mZ, out float outx, out float outy )
	{
		mX = CamMidX + mX * GetZTrans( mZ );
		mY = CamMidY + mY * GetZTrans( mZ );
		
		/*
			ox = mX - MidX;
			oy = mY - MidY;
			R = Math.Cos( Angle * Math.PI/180 );
			I = Math.Sin( Angle * Math.PI/180 );
			dx = ox*R - oy*I;
			dy = ox*I + oy*R;
			mX = MidX + (float)dx;
			mY = MidY + (float)dy;
		 */
		
		outx = mX;
		outy = mY;
	}
	
	//计算反透视变换
	float GetFZTrans( float z )
	{
		float oz = (z - CamZ);
		if( Math.Abs( oz ) < 1 ) {
			oz = 1;
		}
		return StdDis / oz;
	}
	
	//计算透视变换
	float GetZTrans( float z )
	{
		return (z - CamZ) / StdDis;
	}
	
	//-----------------------------------------------------------------
	
	public void MyRefresh()
	{
		//Invalidate();
		
		//因为是界面卡住 所以强制刷新
		Refresh();
	}
	
	//重绘事件
	protected override void OnPaint(PaintEventArgs e)
	{
		//禁用图像模糊效果
		e.Graphics.InterpolationMode = InterpolationMode.Default;
		e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
		e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
		
		//设置绘图目标
		SG.SetObject( e.Graphics );
		
		Graphics g = e.Graphics;
		
		GraphicsState gs = g.Save();
		
		//绘制背景
		g.Clear( Color.WhiteSmoke );
		
		float RolX = Width/2;
		float RolY = Height/2;
		
		//摄像机按照中心位置进行旋转
		//SG.Rotate( RolX, RolY, CamAngle );
		
		//摄像机移动到指定点
		SG.Transfer( -(CamMidX - RolX), -(CamMidY - RolY) );
		
		//按照摄像机中心位置进行放缩
		SG.Scale( CamMidX, CamMidY, GetFZTrans( 0 ) );
		
		//用户绘制区
		try {
			if( G.ccode.b_ExistPython ) {
				PyVar.Draw( g );
			}
		}
		catch( Exception ex ) {
			g.Restore( gs );
			g.DrawString( ex.ToString(), Font13, Brushes.Red, 20, 20 );
		}
		
		g.Restore( gs );
		g.DrawString( "Z:" + CamZ.ToString(), Font13, Brushes.DimGray, 20, 20 );
		
		if( DebugMes != null ) {
			g.DrawString( DebugMes, Font13, Brushes.OrangeRed, 20, 40 );
		}
	}
	
	//-----------------------------------------------------------------
	
	//鼠标滚轮事件
	void UserMouseWheel( object sender, MouseEventArgs e )
	{
		/*
		if( RightisPress ) {
			if( e.Delta > 0 ) {
				CamAngle += 5;
			}
			else {
				CamAngle -= 5;
			}
		}
		else {
			CamZ += e.Delta / 2f;
		}
		*/
		
		
		int x = e.X;
		int y = e.Y;
		
		float  xx, yy;
		GetWorldTrans( x - Width/2, y - Height/2, 0, out xx, out yy );
		
		/*
		if( e.Delta > 0 ) {
			CamZ += 200;
		}
		else {
			CamZ -= 200;
		}
		*/
		if( e.Delta < 0 ) {
			CamZ *= 1.05f;
		}
		else {
			CamZ /= 1.05f;
		}
		
		
		float  xx1, yy1;
		GetWorldTrans( x - Width/2, y - Height/2, 0, out xx1, out yy1 );
		
		CamMidX += (xx - xx1);
		CamMidY += (yy - yy1);
		
		MyRefresh();
	}
	
	//鼠标按下事件
	void UserMouseDown( object sender, MouseEventArgs e )
	{
		this.Select();
		
		int x = e.X;
		int y = e.Y;
		
		Last_mX = x;
		Last_mY = y;
		
		/*
		for( int i = 0; i < GBlockListLenght; ++i ) {
			if( GBlockList[i] == null ) {
				continue;
			}
			float  xx, yy;
			Trans.GetWorldTrans( x - Width/2, y - Height/2, GBlockList[i].Z, out xx, out yy );
			GBlockList[i].MouseDown( xx, yy );
		}
		*/
		
		//如果按下左键
		if( e.Button == MouseButtons.Left ) {
			LeftisPress = true;
		}
		//判断是否按下右键
		if( e.Button == MouseButtons.Right ) {
			RightisPress = true;
		}
		//判断是否按下鼠标中键
		if( e.Button == MouseButtons.Middle ) {
			
		}
		//界面刷新
		MyRefresh();
	}
	
	//鼠标松开事件
	void UserMouseUp( object sender, MouseEventArgs e )
	{
		int x = e.X;
		int y = e.Y;
		
		/*
		for( int i = 0; i < GBlockListLenght; ++i ) {
			if( GBlockList[i] == null ) {
				continue;
			}
			float  xx, yy;
			Trans.GetWorldTrans( x - Width/2, y - Height/2, GBlockList[i].Z, out xx, out yy );
			GBlockList[i].MouseUp( xx, yy );
		}
		*/
		
		if( e.Button == MouseButtons.Left ) {
			LeftisPress = false;
		}
		if( e.Button == MouseButtons.Right ) {
			RightisPress = false;
		}
		if( e.Button == MouseButtons.Middle ) {
			
		}
		//界面刷新
		MyRefresh();
	}
	
	//鼠标移动事件
	void UserMouseMove( object sender, MouseEventArgs e )
	{
		int x = e.X;
		int y = e.Y;
		
		/*
		for( int i = 0; i < GBlockListLenght; ++i ) {
			if( GBlockList[i] == null ) {
				continue;
			}
			float  xx, yy;
			Trans.GetWorldTrans( x - Width/2, y - Height/2, GBlockList[i].Z, out xx, out yy );
			GBlockList[i].MouseMove( xx, yy );
		}
		*/
		
		if( LeftisPress ) {
			
			float ox = -(x - Last_mX);
			float oy = -(y - Last_mY);
			double R = Math.Cos( -CamAngle * Math.PI/180 );
			double I = Math.Sin( -CamAngle * Math.PI/180 );
			double dx = ox*R - oy*I;
			double dy = ox*I + oy*R;
			
			CamMidX += (float)dx * (CamZ/-StdDis);
			CamMidY += (float)dy * (CamZ/-StdDis);
			
			Last_mX = x;
			Last_mY = y;
		}
		if( RightisPress ) {
			//...
		}
		
		MyRefresh();
	}
}
}


